package com.rankeiot.core.util;

import com.rankeiot.core.data.Item;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 集合转换工具
 * @author desire
 */
public class CollectionUtil {
    public static <K, V> Map<K, V> toKeyMap(Collection<V> list, Function<V, K> key) {
        Map<K, V> result = new HashMap(list.size());
        for (V it : list) {
            result.put(key.apply(it), it);
        }
        return result;
    }

    /**
     * 列表到多级Map
     *
     * @param list 列表项
     * @param key  获取一级Key
     * @param key2 获取二级Key
     * @param <K1>
     * @param <K2>
     * @param <V>
     * @return
     */
    public static <K1, K2, V> Map<K1, Map<K2, V>> toMutiMap(Collection<V> list, Function<V, K1> key, Function<V, K2> key2) {
        Map<K1, Map<K2, V>> result = new HashMap();
        for (V it : list) {
            K1 k = key.apply(it);
            Map<K2, V> m = result.get(k);
            if (m == null) {
                m = new HashMap<>();
                result.put(k, m);
            }
            m.put(key2.apply(it), it);
        }
        return result;
    }

    public static <K, V> Map<K, List<V>> toKeyMapList(Collection<V> list, Function<V, K> key) {
        Map<K, List<V>> result = new HashMap();
        for (V it : list) {
            K k = key.apply(it);
            List<V> l1 = result.get(k);
            if (l1 == null) {
                l1 = new ArrayList<>();
                result.put(k, l1);
            }
            l1.add(it);
        }
        return result;
    }

    public static Map<String, String> toMap(Collection<Item> items) {
        return toMap(items, Item::getKey, Item::getTitle);
    }

    public static <K, V, O> Map<K, V> toMap(Collection<O> list, Function<O, K> key, Function<O, V> v) {
      // return list.stream().collect(Collectors.toMap(key,v));
        Map<K, V> result = new HashMap(list.size());
        for (O it : list) {
            result.put(key.apply(it), v.apply(it));
        }
        return result;
    }
    public static <K, V, O> Map<K, V> toMap(O[] list, Function<O, K> key, Function<O, V> v) {
        Map<K, V> result = Arrays
                .stream(list)
                .collect(Collectors.toMap(key,v));
        return result;
    }
//    public static <K,V> List<Item> mapToItemList(Map<K,V> values){
//
//    }

    /**
     * 将数据转换为树形
     *
     * @param list        输入数据
     * @param getKey      获取key
     * @param getParent   获取父级Key
     * @param getChildren 获取子级，获取的子级不能为空
     * @param rootParent
     * @param <K>
     * @param <T>
     * @return
     */
    public static <K, T> List<T> toTree(Collection<T> list, Function<T, K> getKey, Function<T, K> getParent, Function<T, List<T>> getChildren, K rootParent) {
        Map<K, T> dataMap = new HashMap<>();
        List<T> result = new ArrayList<>();
        for (T t : list) {
            K k = getKey.apply(t);
            K p = getParent.apply(t);
            dataMap.put(k, t);
            if (p == null || Objects.equals(p, rootParent)) {
                result.add(t);
            }
        }
        for (T t : list) {
            K p = getParent.apply(t);
            T pv = dataMap.get(p);
            if (pv != null) {//添加子级数据
                getChildren.apply(pv).add(t);
            }
        }
        return result;
    }
    public static <From,To> List<To> map(Collection<From> source,Function<? super From,? extends To> mapper){
       return source.stream().map(mapper).collect(Collectors.toList());
    }
    public static <From,To> Set<To> mapToSet(Collection<From> source,Function<From,To> mapper){
        return source.stream().map(mapper).collect(Collectors.toSet());
    }

    /**
     * 将参数数组按照 k=>v,k=>v 的对应转换为map
     * @param args
     * @return
     */
    public static Map asMap(Object ...args){
        Map result=new HashMap<>();
        int step=2;
        for(int i=0;i+1<args.length;i+=step){
            Object key=args[i];
            Object value=args[i+1];
            result.put(key,value);
        }
        return result;
    }
}
